承襲前一篇Dio 這篇是接著發起request 這次範例是使用News API
response 回來把資料作後續處理
Data model
可以用這個工具把API的JSON格式檔案貼上轉成Model
這邊先只列出比較外層的部分 全部請參考這裡
class News {
String status = "";
int totalResults = -1;
List<Articles> articles = [];
News();
News.fromJson(Map<String, dynamic> json) {
status = json['status'];
totalResults = json['totalResults'];
if (json['articles'] != null) {
articles = [];
json['articles'].forEach((v) {
articles.add(new Articles.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['totalResults'] = this.totalResults;
data['articles'] = this.articles.map((v) => v.toJson()).toList();
return data;
}
}
ApiService部分
apiKey可以替換成自己的
class ApiService {
Future<News> getNews() async {
var response = await HttpUtil().get(
'/everything?q=tesla&from=2021-10-05&sortBy=publishedAt&apiKey=989e07f02f47475daa7020cb0498af8e');
if (response is DioError) {
print(response.response!.statusCode);
return News();
}
return News.fromJson(response.data);
}
}
接著來實際在頁面呼叫
包含Widget, Controller, repository三個部分
關係分別是
Widget <-> Controller <-> repository <-> ApiService.
Widget部分
在等待API fetch data isLoading 完成前,
將會是轉圈圈等待資料回來的狀態, controller的dataList被assign資料後,
Widget部分由Obx立即響應渲染ListView.
class NewsPage extends GetView<NewsPageController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('NewsPage')),
body: SafeArea(
child: Obx(
() => (controller.isLoading)
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: controller.dataList.length,
itemBuilder: (_, index) {
final title = controller.dataList[index].title;
final content = controller.dataList[index].content;
return Card(
child: ListTile(
title: Text(title),
subtitle: Text(content),
),
);
},
),
),
),
);
}
}
Controller部分
在onInit()時fetchAPI
class NewsPageController extends GetxController {
NewsPageController({required this.repository});
final NewsPageRepository repository;
final _isLoading = true.obs;
set isLoading(value) => this._isLoading.value = value;
get isLoading => this._isLoading.value;
final _dataList = <Articles>[].obs;
get dataList => this._dataList.toList();
@override
void onInit() async {
await fetchData();
super.onInit();
}
fetchData() async {
isLoading = true;
final newsResult = await repository.getNews();
_dataList.assignAll(newsResult.articles);
isLoading = false;
}
}
repository部分
abstract class NewsPageRepository {
Future getNews();
}
class NewsPageRepositoryImpl implements NewsPageRepository {
NewsPageRepositoryImpl();
final apiService = ApiService();
@override
Future<News> getNews() async {
return await apiService.getNews();
}
}
最後效果如下
下一篇將為大家介紹Shimmer